package service

import (
	"MyBlogv2/blog-common/HttpCode"
	"MyBlogv2/blog-common/helper"
	"MyBlogv2/blog-common/models"
	"MyBlogv2/blog-common/response"
	"github.com/gin-gonic/gin"
	"strconv"
)

func GetUserHasRole(c *gin.Context) {
	roleId, _ := strconv.Atoi(c.Query("roleId"))
	username := c.Query("username")
	email := c.Query("email")
	roleUserVoList := selectRoleUser(roleId, username, email, 0)
	response.ResponseOK(c, roleUserVoList)
	return
}
func GetUserNoRole(c *gin.Context) {
	roleId, _ := strconv.Atoi(c.Query("roleId"))
	username := c.Query("username")
	email := c.Query("email")
	roleUserVoList := selectRoleUser(roleId, username, email, 1)
	response.ResponseOK(c, roleUserVoList)
	return
}
func AddUserRole(c *gin.Context) {
	var userRoleDto models.UserRoleDto
	if err := c.ShouldBindJSON(&userRoleDto); err != nil {
		response.ResponseError(c, HttpCode.PARAM_ERROR)
		return
	}
	userIds := userRoleDto.UserId
	roleId := userRoleDto.RoleId
	var notUserIds []int
	for _, userId := range userIds {
		models.Db.Create(&models.UserRole{
			RoleId: userId,
			UserId: roleId,
		})
		var count int64
		models.Db.Model(new(models.UserRole)).
			Where("user_id = ?", userId).
			Where("role_id = ?", roleId).
			Count(&count)
		if count == 0 {
			notUserIds = append(notUserIds, userId)
		}
	}
	for _, v := range notUserIds {
		var userRole models.UserRole
		userRole.UserId = v
		userRole.RoleId = roleId
		models.Db.Model(new(models.UserRole)).Create(&userRole)
	}
	response.ResponseOK(c, nil)
	return

}

func DeleteUserRole(c *gin.Context) {
	var userRoleDto models.UserRoleDto
	if err := c.ShouldBindJSON(&userRoleDto); err != nil {
		response.ResponseError(c, HttpCode.PARAM_ERROR)
		return
	}
	models.Db.Model(new(models.UserRole)).Where("user_id in (?)", userRoleDto.UserId).Where("role_id = ?", userRoleDto.RoleId).Delete(new(models.UserRole))
	response.ResponseOK(c, nil)
	return
}

func GetRoleHasUser(c *gin.Context) {
	userId, _ := strconv.Atoi(c.Query("userId"))
	roleName := c.Query("roleName")
	roleKey := c.Query("roleKey")
	roleAllVoList := selectRoleByUserId(userId, roleName, roleKey, 0)
	response.ResponseOK(c, roleAllVoList)
	return
}
func GetRoleNoUser(c *gin.Context) {
	userId, _ := strconv.Atoi(c.Query("userId"))
	roleName := c.Query("roleName")
	roleKey := c.Query("roleKey")
	roleAllVoList := selectRoleByUserId(userId, roleName, roleKey, 1)
	response.ResponseOK(c, roleAllVoList)
	return
}
func selectRoleUser(roleId int, username string, email string, typeOfSelect int) []models.RoleUserVo {
	var roleUserVoList []models.RoleUserVo
	var userIds []int
	db := models.Db.Model(new(models.UserRole)).
		Select("user_id").
		Where("role_id = ?", roleId)
	if typeOfSelect == 1 {
		var userIdsYes []int
		db.Find(&userIdsYes)
		var userIdsAll []int
		models.Db.Model(new(models.UserRole)).
			Distinct("user_id").
			Select("user_id").
			Find(&userIdsAll)
		userIds = helper.DiffOfIntArray(userIdsAll, userIdsYes)
	} else if typeOfSelect == 0 {
		db.Find(&userIds)
	}
	db2 := models.Db.Model(new(models.User)).Where("id in (?)", userIds)
	if username != "" {
		db2.Where("username like ?", "%"+username+"%")
	}
	if email != "" {
		db2.Where("email like ?", "%"+email+"%")
	}
	db2.Find(&roleUserVoList)
	return roleUserVoList

}
func selectRoleByUserId(userId int, roleName string, roleKey string, typeOfSelect int) []models.RoleAllVo {
	var roleAllVo []models.RoleAllVo
	var roleIds []int
	db := models.Db.Model(new(models.UserRole)).
		Select("role_id").
		Where("user_id = ?", userId)
	if typeOfSelect == 1 {
		var roleIdsYes []int
		db.Find(&roleIdsYes)
		var roleIdsAll []int
		models.Db.Model(new(models.UserRole)).
			Distinct("role_id").
			Select("role_id").
			Find(&roleIdsAll)
		roleIds = helper.DiffOfIntArray(roleIdsAll, roleIdsYes)
	} else if typeOfSelect == 0 {
		db.Find(&roleIds)
	}
	db2 := models.Db.Model(new(models.RoleAllVo)).Where("id in (?)", roleIds)
	if roleName != "" {
		db2.Where("role_name like ?", "%"+roleName+"%")
	}
	if roleKey != "" {
		db2.Where("role_key like ?", "%"+roleKey+"%")
	}
	db2.Find(&roleAllVo)
	return roleAllVo

}
